package com.guldan.thrall.web.controller;

import java.io.*;
import java.text.DecimalFormat;
import java.util.*;

import javax.servlet.http.HttpServletRequest;

import com.guldan.core.controller.BaseController;
import com.guldan.core.enums.FileTypeEn;
import com.guldan.core.enums.ProjectRegisterEn;
import com.guldan.core.exception.BusinessException;
import com.guldan.jaina.dto.area.AreaDTO;
import com.guldan.jaina.dto.progress.BarDTO;
import com.guldan.jaina.dto.project.ProjectDTO;
import com.guldan.jaina.dto.projectextensiondetail.ProjectExtDataSampleDTO;
import com.guldan.jaina.dto.projectextensiondetail.ProjectExtensionDetailDTO;
import com.guldan.jaina.dto.projectextensiondic.ProjectExtensionDicDTO;
import com.guldan.jaina.dto.projectregisterbatch.CopyBatchDataDTO;
import com.guldan.jaina.dto.projectregisterupload.ProjectRegisterUploadDTO;
import com.guldan.jaina.provider.IAreaProvider;
import com.guldan.jaina.provider.IProjectProvider;
import net.sf.jxls.transformer.XLSTransformer;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import com.alibaba.fastjson.JSON;
import com.guldan.core.constants.CommonConstant;
import com.guldan.core.dubbo.client.ResponseDTO;
import com.guldan.core.response.ResponseJson;
import com.guldan.core.search.Pagination;
import com.guldan.core.utils.DateUtil;
import com.guldan.jaina.dto.orgbatchsummary.OrgBatchSummaryDTO;
import com.guldan.jaina.dto.orgbatchsummary.OrgBatchSummarySearchDTO;
import com.guldan.jaina.dto.projectregisterbatch.BatchAuditorDTO;
import com.guldan.jaina.dto.projectregisterbatch.ProjectRegisterBatchDTO;
import com.guldan.jaina.dto.projectregisterbatch.ProjectRegisterBatchSearchDTO;
import com.guldan.jaina.dto.register.RegisterTemplateDTO;
import com.guldan.jaina.dto.register.RegisterTemplateDataDTO;
import com.guldan.jaina.dto.register.RegisterTemplateSearchDTO;
import com.guldan.jaina.dto.register.RegisterTemplateXlsDTO;
import com.guldan.jaina.dto.register.summary.SummaryDTO;
import com.guldan.jaina.dto.register.summary.SummaryDetailDTO;
import com.guldan.jaina.dto.register.summary.SummaryFileDTO;
import com.guldan.jaina.dto.register.summary.SummaryUploadDTO;
import com.guldan.jaina.dto.registerfail.RegisterFailDTO;
import com.guldan.jaina.dto.registerfail.RegisterFailSearchDTO;
import com.guldan.jaina.dto.registersuccess.RegisterDeleteDTO;
import com.guldan.jaina.dto.registersuccess.RegisterSuccessDTO;
import com.guldan.jaina.dto.registersuccess.RegisterSuccessSearchDTO;
import com.guldan.jaina.provider.IProjectRegisterProvider;
import com.guldan.core.constants.Constant;
import com.guldan.core.constants.XlsHeaderConstant;
import com.guldan.thrall.util.RegisterExcel;
import com.guldan.thrall.util.RegisterSummaryExcel;

/**
 * Created by Silas.
 * Date: 2016/12/3
 * Time: 17:37
 */

@Controller
@RequestMapping("/projectRegister")
public class ProjectRegisterController extends BaseController {
    protected Logger log = LoggerFactory.getLogger(getClass());

    @Autowired
    private IProjectRegisterProvider iProjectRegisterProvider;

    @Autowired
    private IProjectProvider iProjectProvider;

    @Autowired
    private IAreaProvider iAreaProvider;


//    @Autowired
//    private IProjectProvider iProjectProvider;

    //提交登记上报
    @RequestMapping(value = "/approvalSubmit", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Boolean approvalSubmit(@RequestBody ProjectRegisterBatchSearchDTO dto) throws Exception {
        ResponseDTO<Boolean> response = iProjectRegisterProvider.approvalSubmit(dto.getBatchId());
        if (response.isSuccess())
            return response.getData();
        else {
            throw response.getException();
        }

    }

    //列表查看所有登记失败人员的列表
    @RequestMapping(value = "/registFailList", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Pagination<RegisterFailDTO> registFailList(@RequestBody RegisterFailSearchDTO dto) {
        ResponseDTO<Pagination<RegisterFailDTO>> response = iProjectRegisterProvider.registFailList(dto);
        return response.getData();
    }

    //列表查看所有失败人员的列表
    @RequestMapping(value = "/failList", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Pagination<RegisterSuccessDTO> failList(@RequestBody RegisterSuccessSearchDTO dto) {
        ResponseDTO<Pagination<RegisterSuccessDTO>> response = iProjectRegisterProvider.failList(dto);
        return response.getData();
    }

    //列表查看所有成功人员的列表
    @RequestMapping(value = "/successList", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Pagination<RegisterSuccessDTO> successList(@RequestBody RegisterSuccessSearchDTO dto) {
        ResponseDTO<Pagination<RegisterSuccessDTO>> response = iProjectRegisterProvider.successList(dto);
        return response.getData();
    }

    //下载登记成功，且非没通过的人
    @RequestMapping(value = "/downRegisterSuccess", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    String downRegisterSuccess(HttpServletRequest request, @RequestBody RegisterSuccessSearchDTO dto) {


        dto.setCurrentPage(1);
        dto.setPerPage(1000000);


        ResponseDTO<Pagination<RegisterSuccessDTO>> response = iProjectRegisterProvider.successList(dto);
        List<RegisterSuccessDTO> data = response.getData().getList();

        List<String> headers = new ArrayList<String>();
        for (String header : XlsHeaderConstant.REGISTER_XLS_HEADERS) {
            headers.add(header);
        }

        //获取扩展属性列名
        List<String> extDicNames = new ArrayList<>();
        RegisterSuccessDTO registerSuccessDTO = data.get(0);
        if (registerSuccessDTO.getProjectExtensionDetailList() != null && registerSuccessDTO.getProjectExtensionDetailList().size() > 0) {
            for (ProjectExtensionDetailDTO projectExtensionDetailDTO : registerSuccessDTO.getProjectExtensionDetailList()) {
                headers.add(projectExtensionDetailDTO.getExtName());
            }
        }

        String registerAreaName = "";
        if (dto.getBatchId() != null) {
            ProjectRegisterBatchSearchDTO projectRegisterBatchSearchDTO = new ProjectRegisterBatchSearchDTO();
            projectRegisterBatchSearchDTO.setBatchId(dto.getBatchId());
            ProjectRegisterBatchDTO projectRegisterBatchDTO = iProjectRegisterProvider.getProjectRegisterBatchDTO(projectRegisterBatchSearchDTO).getData();
            registerAreaName = projectRegisterBatchDTO.getAreaName();
        } else if (dto.getSummaryId() != null) {
            OrgBatchSummarySearchDTO orgBatchSummarySearchDTO = new OrgBatchSummarySearchDTO();
            orgBatchSummarySearchDTO.setSummaryId(dto.getSummaryId());
            OrgBatchSummaryDTO orgBatchSummaryDTO = iProjectRegisterProvider.getOrgBatchSummaryDTO(orgBatchSummarySearchDTO).getData();
            registerAreaName = orgBatchSummaryDTO.getAreaName();
        }

        String fileName = (dto.getBatchId() != null ? dto.getBatchId() : dto.getSummaryId()) + "_" + System.currentTimeMillis() + ".xls";
        String url = "/" + Constant.ATTACHMENT_PATH_REGISTER_SUCCESS_DOWN + fileName;

        log.info("register template url:" + url);

        /* 使用poi来生成execl */
        //创建book
        HSSFWorkbook wb = new HSSFWorkbook();
        HSSFCellStyle bodyStyle = wb.createCellStyle();
        bodyStyle.setWrapText(true);  //设置自动适应高度

        //创建sheet
        HSSFSheet sheet = wb.createSheet("sheet1");
        //设置各列的宽度
        sheet.setColumnWidth(0, 15 * 256); //第1列，15个字
        sheet.setColumnWidth(1, 30 * 256); //第2列，30个字

        for (int i = 2; i < headers.size() - 1; i++) {
            sheet.setColumnWidth(i, 20 * 256);
        }

        sheet.setColumnWidth(headers.size() - 1, 100 * 256);  //设置最后一列失败列的宽度

        //设置公共行数据
        //补贴项目名称*
        HSSFRow row0 = sheet.createRow(0);
        HSSFCell cellNum00 = row0.createCell(0);
        HSSFCell cellNum01 = row0.createCell(1);
        cellNum00.setCellValue(XlsHeaderConstant.REGISTER_XLS_COMMON_FIELD[0]);
        cellNum01.setCellValue(data.get(0).getProjectName());

        //补贴项目年度*
        HSSFRow row1 = sheet.createRow(1);
        HSSFCell cellNum10 = row1.createCell(0);
        HSSFCell cellNum11 = row1.createCell(1);
        cellNum10.setCellValue(XlsHeaderConstant.REGISTER_XLS_COMMON_FIELD[1]);
        cellNum11.setCellValue(data.get(0).getYear());

        //补贴发放次数*
        HSSFRow row2 = sheet.createRow(2);
        HSSFCell cellNum20 = row2.createCell(0);
        HSSFCell cellNum21 = row2.createCell(1);
        cellNum20.setCellValue(XlsHeaderConstant.REGISTER_XLS_COMMON_FIELD[2]);
        cellNum21.setCellValue(data.get(0).getSubsidyCount());

        //补贴登记区划*
        HSSFRow row3 = sheet.createRow(3);
        HSSFCell cellNum30 = row3.createCell(0);
        HSSFCell cellNum31 = row3.createCell(1);
        cellNum30.setCellValue(XlsHeaderConstant.REGISTER_XLS_COMMON_FIELD[3]);
        cellNum31.setCellValue(registerAreaName);

        //设置表格标题行数据
        HSSFRow row4 = sheet.createRow(4);
        for (int i = 0; i < headers.size(); i++) {
            row4.createCell(i).setCellValue(headers.get(i));
        }

        //设置表格每条记录行的数据

        for (int i = 5; i < data.size() + 5; i++) {
            HSSFRow row = sheet.createRow(i);

            //基础列
            HSSFCell cellNum0 = row.createCell(0);
            cellNum0.setCellValue(data.get(i - 5).getName());
            HSSFCell cellNum1 = row.createCell(1);
            cellNum1.setCellValue(data.get(i - 5).getIdentNumber());
            HSSFCell cellNum2 = row.createCell(2);
            cellNum2.setCellValue(data.get(i - 5).getBankName());
            HSSFCell cellNum3 = row.createCell(3);
            cellNum3.setCellValue(data.get(i - 5).getBankNumber());
            HSSFCell cellNum4 = row.createCell(4);
            cellNum4.setCellValue(data.get(i - 5).getSubsidyMoney().toString());

            //扩展属性列
            for (int j = 0; j < headers.size() - 6; j++) {
                HSSFCell cellNum = row.createCell(j + 5);
                cellNum.setCellValue(data.get(i - 5).getProjectExtensionDetailList().get(j).getExtContent());
            }
        }

        String out = request.getRealPath("/") + Constant.ATTACHMENT_PATH_REGISTER_SUCCESS_DOWN + fileName;
        FileOutputStream fileOut = null;
        try {
            fileOut = new FileOutputStream(out);
            wb.write(fileOut);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileOut.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return url;

    }

    //删除某个已经成功登记居民
    @RequestMapping(value = "/deleteCitizen", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Boolean deleteCitizen(@RequestBody RegisterDeleteDTO dto) {
        ResponseDTO<Boolean> response = iProjectRegisterProvider.deleteCitizen(dto);
        return response.getData();
    }

    //删除某个登记批次
    @RequestMapping(value = "/deleteRegisterBatch", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Boolean deleteRegisterBatch(@RequestBody ProjectRegisterBatchDTO dto) {
        ResponseDTO<Boolean> response = iProjectRegisterProvider.deleteRegisterBatch(dto.getBatchId());
        return response.getData();
    }

    //获取某个已经成功登记的居民信息
    @RequestMapping(value = "/getCitizen", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    RegisterSuccessDTO getCitizen(@RequestBody RegisterSuccessDTO dto) {
        ResponseDTO<RegisterSuccessDTO> response = iProjectRegisterProvider.getCitizen(dto.getRegisterId());
        return response.getData();
    }

    //保存某个已经成功登记的居民信息
    @RequestMapping(value = "/saveCitizen", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    RegisterSuccessDTO saveCitizen(@RequestBody RegisterSuccessDTO dto) {
        ResponseDTO<RegisterSuccessDTO> response = iProjectRegisterProvider.saveCitizen(dto);
        return response.getData();
    }

    //列表返回已经成功登记的居民信息
    @RequestMapping(value = "/listCitizen", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Pagination<RegisterSuccessDTO> listCitizen(@RequestBody RegisterSuccessSearchDTO dto) {
        ResponseDTO<Pagination<RegisterSuccessDTO>> response = iProjectRegisterProvider.listCitizen(dto);
        return response.getData();
    }

    //列表返回当前正在登记中的项目批次记录
    @RequestMapping(value = "/townsRegistingList", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Pagination<ProjectRegisterBatchDTO> townsRegistingList(@RequestBody ProjectRegisterBatchSearchDTO dto) {
        ResponseDTO<Pagination<ProjectRegisterBatchDTO>> response = iProjectRegisterProvider.townsRegistingList(dto);
        return response.getData();
    }

    //列表返回已经提交上报的项目批次列表
    @RequestMapping(value = "/townsRegistedList", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Pagination<ProjectRegisterBatchDTO> townsRegistedList(@RequestBody ProjectRegisterBatchSearchDTO dto) {
        ResponseDTO<Pagination<ProjectRegisterBatchDTO>> response = iProjectRegisterProvider.townsRegistedList(dto);
        return response.getData();
    }

    //列表返回已经完结的项目批次列表
    @RequestMapping(value = "/finishBatchList", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Pagination<ProjectRegisterBatchDTO> finishBatchList(@RequestBody ProjectRegisterBatchSearchDTO dto) {
        ResponseDTO<Pagination<ProjectRegisterBatchDTO>> response = iProjectRegisterProvider.finishBatchList(dto);
        return response.getData();
    }


    //列表返回乡镇人员复核,当前需要操作的批次列表
    @RequestMapping(value = "/townsAuditoringList", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Pagination<ProjectRegisterBatchDTO> townsAuditoringList(@RequestBody ProjectRegisterBatchSearchDTO dto) {
        ResponseDTO<Pagination<ProjectRegisterBatchDTO>> response = iProjectRegisterProvider.townsAuditoringList(dto);
        return response.getData();
    }

    //列表返回乡镇人员复核,复核通过的批次列表
    @RequestMapping(value = "/townsAuditoredList", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Pagination<ProjectRegisterBatchDTO> townsAuditoredList(@RequestBody ProjectRegisterBatchSearchDTO dto) {
        ResponseDTO<Pagination<ProjectRegisterBatchDTO>> response = iProjectRegisterProvider.townsAuditoredList(dto);
        return response.getData();
    }

    //对批次操作，复核通过、复核不通过、上报
    @RequestMapping(value = "/townsAuditorSubmit", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Boolean townsAuditorSubmit(@RequestBody BatchAuditorDTO dto) {
        ResponseDTO<Boolean> response = iProjectRegisterProvider.townsAuditorSubmit(dto);
        return response.getData();
    }

    //对登记记录进行操作，复核通过、复核不通过
    @RequestMapping(value = "/townsAuditorSubmitForRegister", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Boolean townsAuditorSubmitForRegister(@RequestBody BatchAuditorDTO dto) {
        ResponseDTO<Boolean> response = iProjectRegisterProvider.townsAuditorSubmitForRegister(dto);
        return response.getData();
    }

    //列表查看某批次下待复核的登记记录列表
    @RequestMapping(value = "/townsAuditorWaitCizList", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Pagination<RegisterSuccessDTO> townsAuditorWaitCizList(@RequestBody RegisterSuccessSearchDTO dto) {
        ResponseDTO<Pagination<RegisterSuccessDTO>> response = iProjectRegisterProvider.townsAuditorWaitCizList(dto);
        return response.getData();
    }

    /**
     * 下载人员填报
     *
     * @param request
     * @param dto
     * @return
     */
    @RequestMapping(value = "/downTemplate", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    String downTemplate(HttpServletRequest request,
                        @RequestBody RegisterTemplateSearchDTO dto) throws Exception {
        ResponseDTO<List<RegisterTemplateDTO>> response = iProjectRegisterProvider.needReportingList(dto);
        List<RegisterTemplateDTO> data = response.getData();
        List<String> headers = new ArrayList<String>();
        for (String header : XlsHeaderConstant.REGISTER_XLS_HEADERS) {
            headers.add(header);
        }

        if (data != null && data.size() > 0) {
            headers.addAll(data.get(0).getExtNames());
        }
        //generating xls and return file url
//        String fileName = dto.getProjectId() + "_" + dto.getYear() + "_" + dto.getSubsidyCount() + "_" + DateUtil.toLocaleString(new Date(), "yyyyMMdd") + ".xls";
        String fileName = "";
        String url = "";
        try {

            ProjectDTO projectDTO = iProjectProvider.get(dto.getProjectId()).getData();
            AreaDTO areaDTO = iAreaProvider.get(dto.getAreaId()).getData();

            fileName = dto.getYear() + "年度-" + projectDTO.getProjectName() + "-" + areaDTO.getAreaName() + "-" + dto.getSubsidyCount() + "-" + System.currentTimeMillis() + ".xls";
//            url = "/" + Constant.ATTACHMENT_PATH_REGISTER + fileName;

            String is = request.getRealPath("/") + FileTypeEn.template.getMean() + Constant.REGISTER_XLS_TEMPLATE_NAME;
            String os = request.getRealPath("/") + FileTypeEn.attachment.getMean() + fileName;

            /*
            Context context = PoiTransformer.createInitialContext();

            context.putVar("projectName", projectDTO.getProjectName());
            context.putVar("year", dto.getYear());
            context.putVar("subsidyCount", dto.getSubsidyCount());
            context.putVar("areaName", areaDTO.getAreaName());

            context.putVar("headers", headers);
            context.putVar("data", response.getData());
            JxlsHelper.getInstance().processGridTemplateAtCell(is, os, context, "name,identNumber,bankName,bankNumber,money", "Sheet1!A1");
*/


            Map<String, Object> context = new HashMap<>();
            context.put("projectName", projectDTO.getProjectName());
            context.put("year", dto.getYear());
            context.put("subsidyCount", dto.getSubsidyCount());
            context.put("areaName", areaDTO.getAreaName());

            context.put("headers", headers);
            context.put("data", response.getData());
            XLSTransformer former = new XLSTransformer();
            former.transformXLS(is, context, os);


        } catch (Exception ex) {
            ex.printStackTrace();
            throw new BusinessException(ex.getMessage());
        }
        log.info("register template url:" + url);


        url = Constant.DOWNLOAD_URL_BASE + "?fileName=" + fileName + "&type=" + FileTypeEn.attachment.getCode();


        return url;
    }

    /**
     * 系统内新建登记批次
     *
     * @param request
     * @param dto
     * @return
     */
    @RequestMapping(value = "/createRegisterBatch", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    BarDTO createRegisterBatch(@RequestBody RegisterTemplateSearchDTO dto) throws Exception {
        ResponseDTO<BarDTO> response = iProjectRegisterProvider.createRegisterBatch(dto);
        if (response.isSuccess()) {
            return response.getData();
        } else {
            throw response.getException();
        }
    }

    /**
     * 上传补贴登记
     *
     * @param dto
     * @return
     */
    @RequestMapping(value = "/uploadCitizen", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    BarDTO uploadCitizen(HttpServletRequest request) throws Exception {
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
                request.getSession().getServletContext());
        String path = null;
        if (multipartResolver.isMultipart(request)) {
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            Iterator<String> iter = multiRequest.getFileNames();
            if (iter.hasNext()) {
                String fileName = iter.next();
                MultipartFile file = null;
                try {
                    file = multiRequest.getFile(fileName);
                } catch (Exception e) {
                    log.info(e.getMessage());
                    e.printStackTrace();
                    throw e;
                }
                if (file != null) {
                    String subDirectory = DateUtil.toLocaleString(new Date(), "yyyyMMdd");
                    String filePath = request.getRealPath("/") + Constant.ATTACHMENT_PATH_REGISTER_UP + subDirectory;

                    File f = new File(filePath);
                    if (!f.exists())
                        f.mkdirs();
                    path = filePath + "/" + file.getOriginalFilename();
                    try {
                        file.transferTo(new File(path));
                    } catch (IllegalStateException | IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        throw e;
                    }
                }
            }
            log.info("handling data packaging");
            //handling data packaging
            RegisterTemplateXlsDTO xlsDto = null;
            RegisterExcel excel = new RegisterExcel();
            try {
                xlsDto = excel.readExcel(path);
                List<RegisterTemplateDataDTO> list = xlsDto.getList();
                if (list != null && list.size() > 0) {
                    log.info(JSON.toJSONString(list));
                }
            } catch (IOException | BusinessException e) {
                // TODO Auto-generated catch block
                log.info(e.getMessage());
                e.printStackTrace();
                throw e;
            }

            log.info("down：" + xlsDto.getHeader().toString());

            //call dubbo
            ResponseDTO<BarDTO> responseDTO = iProjectRegisterProvider.uploadCitizen(xlsDto.getHeader(), xlsDto.getList());
            if (responseDTO.isSuccess())
                return responseDTO.getData();
            else {
                throw responseDTO.getException();
            }
        }
        return null;
    }


    //获取上传动作记录
    @RequestMapping(value = "/listUploadRecord", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    List<ProjectRegisterUploadDTO> listUploadRecord(@RequestBody ProjectRegisterUploadDTO dto) {
        ResponseDTO<List<ProjectRegisterUploadDTO>> response = iProjectRegisterProvider.listUploadRecord(dto.getBatchId());
        return response.getData();
    }

    //下载登记失败人员列表
    @RequestMapping(value = "/downRegisterFail", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    String downRegisterFail(HttpServletRequest request, @RequestBody RegisterFailSearchDTO dto) {
        dto.setCurrentPage(1);
        dto.setPerPage(1000000);

        ResponseDTO<Pagination<RegisterFailDTO>> response = iProjectRegisterProvider.registFailList(dto);
        List<RegisterFailDTO> data = response.getData().getList();

        List<String> headers = new ArrayList<String>();
        for (String header : XlsHeaderConstant.REGISTER_XLS_HEADERS) {
            headers.add(header);
        }

        //获取扩展属性列名
        List<String> extDicNames = new ArrayList<>();
        RegisterFailDTO registerFailDTO = data.get(0);
        if (StringUtils.isNotBlank(registerFailDTO.getExtData())) {
            for (ProjectExtDataSampleDTO dataSampleDTO : registerFailDTO.getExtDataList()) {
                headers.add(dataSampleDTO.getExtName());
            }
        }

        /*ResponseDTO<List<ProjectExtensionDicDTO>> responseDTO = iProjectProvider.listByProjectId(data.get(0).getProjectId());
        if (data != null && data.size() > 0) {
            headers.addAll(data.get(0).getExtNames());
        }*/

        //iProjectProvider.listByProjectId();

        //if (StringUtils.isNotBlank(data.get(0).getExtData())) headers.add("扩展属性");
        headers.add("失败原因");  //最后一列
        //generating xls and return file url
        String fileName = dto.getBatchId() + "_" + System.currentTimeMillis() + ".xls";
        String url = "/" + Constant.ATTACHMENT_PATH_REGISTER_FAIL_DOWN + fileName;
        try {

            Map<String, Object> context = new HashMap<>();
            context.put("projectName", data.get(0).getProjectName());
            context.put("year", data.get(0).getYear());
            context.put("subsidyCount", data.get(0).getSubsidyCount());
            context.put("registerAreaName", data.get(0).getRegisterAreaName());

            context.put("headers", headers);
            context.put("data", response.getData().getList());
            context.put("extDicNames", extDicNames);
            XLSTransformer former = new XLSTransformer();

//            former.transformXLS(request.getRealPath("/") + Constant.REGISTER_FAIL_XLS_TEMPLATE, context, request.getRealPath("/") + Constant.ATTACHMENT_PATH_REGISTER_FAIL_DOWN + fileName);

        } catch (Exception ex) {
            ex.printStackTrace();
            throw new BusinessException(ex.getMessage());
        }
        log.info("register template url:" + url);



        /* 使用poi来生成execl */
        //创建book
        HSSFWorkbook wb = new HSSFWorkbook();
        HSSFCellStyle bodyStyle = wb.createCellStyle();
        bodyStyle.setWrapText(true);  //设置自动适应高度

        //创建sheet
        HSSFSheet sheet = wb.createSheet("sheet1");
        //设置各列的宽度
        sheet.setColumnWidth(0, 15 * 256); //第1列，15个字
        sheet.setColumnWidth(1, 30 * 256); //第2列，30个字

        for (int i = 2; i < headers.size() - 1; i++) {
            sheet.setColumnWidth(i, 20 * 256);
        }

        sheet.setColumnWidth(headers.size() - 1, 100 * 256);  //设置最后一列失败列的宽度

        //设置公共行数据
        //补贴项目名称*
        HSSFRow row0 = sheet.createRow(0);
        HSSFCell cellNum00 = row0.createCell(0);
        HSSFCell cellNum01 = row0.createCell(1);
        cellNum00.setCellValue(XlsHeaderConstant.REGISTER_XLS_COMMON_FIELD[0]);
        cellNum01.setCellValue(data.get(0).getProjectName());

        //补贴项目年度*
        HSSFRow row1 = sheet.createRow(1);
        HSSFCell cellNum10 = row1.createCell(0);
        HSSFCell cellNum11 = row1.createCell(1);
        cellNum10.setCellValue(XlsHeaderConstant.REGISTER_XLS_COMMON_FIELD[1]);
        cellNum11.setCellValue(data.get(0).getYear());

        //补贴发放次数*
        HSSFRow row2 = sheet.createRow(2);
        HSSFCell cellNum20 = row2.createCell(0);
        HSSFCell cellNum21 = row2.createCell(1);
        cellNum20.setCellValue(XlsHeaderConstant.REGISTER_XLS_COMMON_FIELD[2]);
        cellNum21.setCellValue(data.get(0).getSubsidyCount());

        //补贴登记区划*
        HSSFRow row3 = sheet.createRow(3);
        HSSFCell cellNum30 = row3.createCell(0);
        HSSFCell cellNum31 = row3.createCell(1);
        cellNum30.setCellValue(XlsHeaderConstant.REGISTER_XLS_COMMON_FIELD[3]);
        cellNum31.setCellValue(data.get(0).getRegisterAreaName());

        //设置表格标题行数据
        HSSFRow row4 = sheet.createRow(4);
        for (int i = 0; i < headers.size(); i++) {
            row4.createCell(i).setCellValue(headers.get(i));
        }

        //设置表格每条记录行的数据

        for (int i = 5; i < data.size() + 5; i++) {
            HSSFRow row = sheet.createRow(i);

            //基础列
            HSSFCell cellNum0 = row.createCell(0);
            cellNum0.setCellValue(data.get(i - 5).getName());
            HSSFCell cellNum1 = row.createCell(1);
            cellNum1.setCellValue(data.get(i - 5).getIdentNumber());
            HSSFCell cellNum2 = row.createCell(2);
            cellNum2.setCellValue(data.get(i - 5).getBankName());
            HSSFCell cellNum3 = row.createCell(3);
            cellNum3.setCellValue(data.get(i - 5).getBankNumber());
            HSSFCell cellNum4 = row.createCell(4);
            cellNum4.setCellValue(data.get(i - 5).getSubsidyMoney());

            //扩展属性列
            for (int j = 0; j < headers.size() - 6; j++) {
                HSSFCell cellNum = row.createCell(j + 5);
                cellNum.setCellValue(data.get(i - 5).getExtDataList().get(j).getExtContent());
            }

            //失败列
            HSSFCell cellFail = row.createCell(headers.size() - 1);
            cellFail.setCellStyle(bodyStyle);
            cellFail.setCellValue(new HSSFRichTextString(data.get(i - 5).getFailReason()));
        }

        String out = request.getRealPath("/") + Constant.ATTACHMENT_PATH_REGISTER_FAIL_DOWN + fileName;
        FileOutputStream fileOut = null;
        try {
            fileOut = new FileOutputStream(out);
            wb.write(fileOut);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileOut.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return url;

    }


    //下载登记成功，但是审核失败的人员列表
    @RequestMapping(value = "/downAuditFail", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    String downAuditFail(HttpServletRequest request, @RequestBody RegisterSuccessSearchDTO dto) {
        dto.setCurrentPage(1);
        dto.setPerPage(1000000);

        ResponseDTO<Pagination<RegisterSuccessDTO>> response = iProjectRegisterProvider.failList(dto);
        List<RegisterSuccessDTO> data = response.getData().getList();

        List<String> headers = new ArrayList<String>();
        for (String header : XlsHeaderConstant.REGISTER_XLS_HEADERS) {
            headers.add(header);
        }

        //获取扩展属性列名
        List<String> extDicNames = new ArrayList<>();
        RegisterSuccessDTO registerSuccessDTO = data.get(0);
        if (registerSuccessDTO.getProjectExtensionDetailList() != null && registerSuccessDTO.getProjectExtensionDetailList().size() > 0) {
            for (ProjectExtensionDetailDTO detailDTO : registerSuccessDTO.getProjectExtensionDetailList()) {
                headers.add(detailDTO.getExtName());
            }
        }

        headers.add("失败原因");  //最后一列

        String fileName = dto.getBatchId() + "_" + System.currentTimeMillis() + ".xls";
        String url = "/" + Constant.ATTACHMENT_PATH_REGISTER_FAIL_DOWN + fileName;

        log.info("register template url:" + url);



        /* 使用poi来生成execl */
        //创建book
        HSSFWorkbook wb = new HSSFWorkbook();
        HSSFCellStyle bodyStyle = wb.createCellStyle();
        bodyStyle.setWrapText(true);  //设置自动适应高度

        //创建sheet
        HSSFSheet sheet = wb.createSheet("sheet1");
        //设置各列的宽度
        sheet.setColumnWidth(0, 15 * 256); //第1列，15个字
        sheet.setColumnWidth(1, 30 * 256); //第2列，30个字

        for (int i = 2; i < headers.size() - 1; i++) {
            sheet.setColumnWidth(i, 20 * 256);
        }

        sheet.setColumnWidth(headers.size() - 1, 100 * 256);  //设置最后一列失败列的宽度

        //设置公共行数据
        //补贴项目名称*
        HSSFRow row0 = sheet.createRow(0);
        HSSFCell cellNum00 = row0.createCell(0);
        HSSFCell cellNum01 = row0.createCell(1);
        cellNum00.setCellValue(XlsHeaderConstant.REGISTER_XLS_COMMON_FIELD[0]);
        cellNum01.setCellValue(data.get(0).getProjectName());

        //补贴项目年度*
        HSSFRow row1 = sheet.createRow(1);
        HSSFCell cellNum10 = row1.createCell(0);
        HSSFCell cellNum11 = row1.createCell(1);
        cellNum10.setCellValue(XlsHeaderConstant.REGISTER_XLS_COMMON_FIELD[1]);
        cellNum11.setCellValue(data.get(0).getYear());

        //补贴发放次数*
        HSSFRow row2 = sheet.createRow(2);
        HSSFCell cellNum20 = row2.createCell(0);
        HSSFCell cellNum21 = row2.createCell(1);
        cellNum20.setCellValue(XlsHeaderConstant.REGISTER_XLS_COMMON_FIELD[2]);
        cellNum21.setCellValue(data.get(0).getSubsidyCount());

        //补贴登记区划*
        HSSFRow row3 = sheet.createRow(3);
        HSSFCell cellNum30 = row3.createCell(0);
        HSSFCell cellNum31 = row3.createCell(1);
        cellNum30.setCellValue(XlsHeaderConstant.REGISTER_XLS_COMMON_FIELD[3]);
        cellNum31.setCellValue(data.get(0).getAreaName());

        //设置表格标题行数据
        HSSFRow row4 = sheet.createRow(4);
        for (int i = 0; i < headers.size(); i++) {
            row4.createCell(i).setCellValue(headers.get(i));
        }

        //设置表格每条记录行的数据

        for (int i = 5; i < data.size() + 5; i++) {
            HSSFRow row = sheet.createRow(i);

            //基础列
            HSSFCell cellNum0 = row.createCell(0);
            cellNum0.setCellValue(data.get(i - 5).getName());
            HSSFCell cellNum1 = row.createCell(1);
            cellNum1.setCellValue(data.get(i - 5).getIdentNumber());
            HSSFCell cellNum2 = row.createCell(2);
            cellNum2.setCellValue(data.get(i - 5).getBankName());
            HSSFCell cellNum3 = row.createCell(3);
            cellNum3.setCellValue(data.get(i - 5).getBankNumber());
            HSSFCell cellNum4 = row.createCell(4);
            cellNum4.setCellValue(data.get(i - 5).getSubsidyMoney().toString());

            //扩展属性列
            for (int j = 0; j < headers.size() - 6; j++) {
                HSSFCell cellNum = row.createCell(j + 5);
                cellNum.setCellValue(data.get(i - 5).getProjectExtensionDetailList().get(j).getExtContent());
            }

            //失败列
            HSSFCell cellFail = row.createCell(headers.size() - 1);
            cellFail.setCellStyle(bodyStyle);
            String failReason = ProjectRegisterEn.getMean(data.get(i - 5).getState());
            if (StringUtils.isNotBlank(data.get(i - 5).getFailReason()))
                failReason += ":" + data.get(i - 5).getFailReason();
            cellFail.setCellValue(new HSSFRichTextString(failReason));
        }

        String out = request.getRealPath("/") + Constant.ATTACHMENT_PATH_REGISTER_FAIL_DOWN + fileName;
        FileOutputStream fileOut = null;
        try {
            fileOut = new FileOutputStream(out);
            wb.write(fileOut);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileOut.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return url;

    }


    /*主管部门审批*/
    //+++++++++++++++++++++++++++++++++++++++++++++++
    //主管部门,待审批批次列表
    @RequestMapping(value = "/orgAuditorList", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Pagination<ProjectRegisterBatchDTO> orgAuditorList(@RequestBody ProjectRegisterBatchSearchDTO searchDTO) {
        ResponseDTO<Pagination<ProjectRegisterBatchDTO>> response = iProjectRegisterProvider.orgAuditorList(searchDTO);
        return response.getData();
    }

    //对批次进行审批，审批通过、审批不通过
    @RequestMapping(value = "/orgAuditorApproval", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Boolean orgAuditorApproval(@RequestBody BatchAuditorDTO dto) {
        ResponseDTO<Boolean> response = iProjectRegisterProvider.orgAuditorApproval(dto);
        return response.getData();
    }

    //对登记人员记录进行审批，审批通过、审批不通过
    @RequestMapping(value = "/orgAuditorApprovalForRegister", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Boolean orgAuditorApprovalForRegister(@RequestBody BatchAuditorDTO dto) {
        ResponseDTO<Boolean> response = iProjectRegisterProvider.orgAuditorApprovalForRegister(dto);
        return response.getData();
    }

    //对批次进行汇总上报
    @RequestMapping(value = "/orgAuditorSubmit", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Boolean orgAuditorSubmit(@RequestBody BatchAuditorDTO dto) {
        ResponseDTO<Boolean> response = iProjectRegisterProvider.orgAuditorSubmit(dto);
        return response.getData();
    }

    //主管部门上报汇总后，汇总批次记录
    @RequestMapping(value = "/orgBatchSummaryList", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Pagination<OrgBatchSummaryDTO> orgBatchSummaryList(@RequestBody OrgBatchSummarySearchDTO searchDTO) {
        ResponseDTO<Pagination<OrgBatchSummaryDTO>> response = iProjectRegisterProvider.orgBatchSummaryList(searchDTO);
        return response.getData();
    }

    //获取某个批次汇总下的登记成功人员记录
    @RequestMapping(value = "/orgAuditorRegisterList", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Pagination<RegisterSuccessDTO> orgAuditorRegisterList(@RequestBody RegisterSuccessSearchDTO searchDTO) {
        ResponseDTO<Pagination<RegisterSuccessDTO>> response = iProjectRegisterProvider.orgAuditorRegisterList(searchDTO);
        return response.getData();
    }


    /*区县财政审批*/
    //+++++++++++++++++++++++++++++++++++++++++++++++
    //财政待审批批次汇总记录
    @RequestMapping(value = "/financeAuditorList", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Pagination<OrgBatchSummaryDTO> financeAuditorList(@RequestBody OrgBatchSummarySearchDTO searchDTO) {
        ResponseDTO<Pagination<OrgBatchSummaryDTO>> response = iProjectRegisterProvider.financeAuditorList(searchDTO);
        return response.getData();
    }

    //对批次汇总记录进行审批，审批通过、审批不通过
    @RequestMapping(value = "/financeAuditorApproval", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Boolean financeAuditorApproval(@RequestBody BatchAuditorDTO dto) {
        ResponseDTO<Boolean> response = iProjectRegisterProvider.financeAuditorApproval(dto);
        return response.getData();
    }

    //查看某批次汇总下的登记成功人员记录
    @RequestMapping(value = "/financeAuditorRegisterList", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Pagination<RegisterSuccessDTO> financeAuditorRegisterList(@RequestBody RegisterSuccessSearchDTO dto) {
        ResponseDTO<Pagination<RegisterSuccessDTO>> response = iProjectRegisterProvider.financeAuditorRegisterList(dto);
        return response.getData();
    }

    //财政通过审批的批次汇总列表
    @RequestMapping(value = "/financeAuditoredSummaryBatchList", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Pagination<OrgBatchSummaryDTO> financeAuditoredSummaryBatchList(@RequestBody OrgBatchSummarySearchDTO dto) {
        ResponseDTO<Pagination<OrgBatchSummaryDTO>> response = iProjectRegisterProvider.financeAuditoredSummaryBatchList(dto);
        return response.getData();
    }

    //生成代发文件
    @RequestMapping(value = "/financeCreatedFile", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    Boolean financeCreatedFile(HttpServletRequest request, @RequestBody OrgBatchSummarySearchDTO dto) {
        String summaryId = dto.getSummaryId();
        ResponseDTO<SummaryFileDTO> response = iProjectRegisterProvider.financeCreatedFile(summaryId);
        SummaryFileDTO data = response.getData();

        String key = String.format(CommonConstant.KEY_FINANCE_CREATE_DATA, data.getSummaryDTO().getSummaryId());
        List<RegisterSuccessDTO> dataList = (List<RegisterSuccessDTO>) cacheService.getCache(key);
        cacheService.removeCache(key);
        SummaryDTO summaryDTO = data.getSummaryDTO();

        //generating xls and return file url
        String fileName = summaryId + ".xls";
        String url = "/" + Constant.ATTACHMENT_PATH_SUMMARY_DOWN + fileName;
        try {
            /*InputStream is = new FileInputStream(request.getRealPath("/") + Constant.SUMMARY_XLS_TEMPLATE);
            OutputStream os = new FileOutputStream(request.getRealPath("/") + Constant.ATTACHMENT_PATH_SUMMARY_DOWN + fileName);
            Context context = PoiTransformer.createInitialContext();
            context.putVar("summary", summaryDTO.getSummaryId());
            context.putVar("project", summaryDTO.getProjectName());
            context.putVar("registerArea", summaryDTO.getRegisterArea());
            context.putVar("count", summaryDTO.getTotalCount());
            context.putVar("money", summaryDTO.getTotalMoney());
            context.putVar("datas", data.getList());
            JxlsHelper jxlsHelper = JxlsHelper.getInstance();
            jxlsHelper.setHideTemplateSheet(false);
            jxlsHelper.processTemplateAtCell(is, os, context, "Sheet1!A1");*/

            DecimalFormat df = new DecimalFormat("#.00");

            Map<String, Object> context = new HashMap<>();
            context.put("summary", summaryDTO.getSummaryId());
            context.put("project", summaryDTO.getProjectName());
            context.put("registerArea", summaryDTO.getRegisterArea());
            context.put("count", summaryDTO.getTotalCount());
            context.put("money", df.format(summaryDTO.getTotalMoney().doubleValue()));
            context.put("datas", dataList);
            XLSTransformer former = new XLSTransformer();
            former.transformXLS(request.getRealPath("/") + Constant.SUMMARY_XLS_TEMPLATE, context, request.getRealPath("/") + Constant.ATTACHMENT_PATH_SUMMARY_DOWN + fileName);

        } catch (Exception ex) {
            ex.printStackTrace();
        }
        log.info("summary created file:" + url);
        iProjectRegisterProvider.updateSummaryState(CommonConstant.SUMMARY_PHASE_CREATE, summaryId, url);
        return Boolean.TRUE;
    }


    //下载代发文件
    @RequestMapping(value = "/financeDownFile", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    String financeDownFile(@RequestBody OrgBatchSummarySearchDTO dto) {
        String summaryId = dto.getSummaryId();
        //generating xls and return file url
        String fileName = summaryId + ".xls";
        String url = "/" + Constant.ATTACHMENT_PATH_SUMMARY_DOWN + fileName;
        iProjectRegisterProvider.updateSummaryState(CommonConstant.SUMMARY_PHASE_DOWNLOAD, summaryId, null);
        return url;
    }

    //银行回执上传
    @RequestMapping(value = "/financeUploadReceipt", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    BarDTO financeUploadReceipt(HttpServletRequest request) throws Exception {
        String summaryId = request.getParameter("summaryId");
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
                request.getSession().getServletContext());
        String path = null;
        ResponseDTO<BarDTO> responseDTO = new ResponseDTO<>();
        try {


            if (multipartResolver.isMultipart(request)) {
                MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
                Iterator<String> iter = multiRequest.getFileNames();
                if (iter.hasNext()) {
                    MultipartFile file = multiRequest.getFile(iter.next());
                    if (file != null) {
                        String subDirectory = DateUtil.toLocaleString(new Date(), "yyyyMMdd");
                        String filePath = request.getRealPath("/") + Constant.ATTACHMENT_PATH_SUMMARY_UP + subDirectory;
                        File f = new File(filePath);
                        if (!f.exists())
                            f.mkdirs();
                        path = filePath + "/" + file.getOriginalFilename();
                        try {
                            file.transferTo(new File(path));
                        } catch (IllegalStateException | IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }

                //handling data packaging
                SummaryUploadDTO xlsDto = null;
                RegisterSummaryExcel excel = new RegisterSummaryExcel();

                xlsDto = excel.readExcel(path, summaryId);
                List<SummaryDetailDTO> list = xlsDto.getList();

                //call dubbo
                responseDTO = iProjectRegisterProvider.financeUploadReceipt(summaryId, list);

                if (responseDTO.isSuccess())
                    return responseDTO.getData();
                else {
                    throw responseDTO.getException();
                }
            }
        } catch (Exception ex) {
            throw ex;
        }
        return responseDTO.getData();
    }

    //登记批次一键结转
    @RequestMapping(value = "/copyBatchData ", method = RequestMethod.POST)
    @ResponseJson
    public
    @ResponseBody
    BarDTO copyBatchData(@RequestBody CopyBatchDataDTO dto) throws Exception {
        ResponseDTO<BarDTO> response = iProjectRegisterProvider.copyBatchData(dto);
        if (response.isSuccess())
            return response.getData();
        else {
            throw response.getException();
        }
    }

}
